/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.service.permission.impl;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.service.MetaService;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.rbac.cache.*;
import com.je.rbac.service.permission.PermissionLoadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

@Service
public class PermissionLoadServiceImpl implements PermissionLoadService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private RolePermCache rolePermCache;
    @Autowired
    private DevelopRolePermCache developRolePermCache;
    @Autowired
    private DepartmentPermCache departmentPermCache;
    @Autowired
    private PermGroupPermCache permGroupPermCache;
    @Autowired
    private OrgPermCache orgPermCache;
    @Autowired
    private UserPermCache userPermCache;
    @Autowired
    private AccountPermissionCache accountPermissionCache;
    @Autowired
    private FuncPermissionCache funcPermissionCache;

    @Override
    @Async
    public Future<Boolean> reloadRolePermCache(List<String> roleIdList, boolean withPermGroup) {
        if (roleIdList == null || roleIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        List<String> permGroupIdList = new ArrayList<>();
        if (withPermGroup) {
            reloadPermGroupPermCache(permGroupIdList, false);
        }

        //清除相关账号
        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_VACCOUNTROLE", ConditionsWrapper.builder().in("ACCOUNTROLE_ROLE_ID", roleIdList));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; accountRoleBeanList != null && !accountRoleBeanList.isEmpty() && i < accountRoleBeanList.size(); i++) {
            accountIdList.add(accountRoleBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }
        accountPermissionCache.removeCache(accountIdList);
        funcPermissionCache.clear();
        rolePermCache.removeCache(roleIdList);
        //获取权限组权限
        List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder().in("JE_RBAC_ROLE_ID", roleIdList));
        for (int i = 0; roleBeanList != null && !roleBeanList.isEmpty() && i < roleBeanList.size(); i++) {
            if (!Strings.isNullOrEmpty(roleBeanList.get(i).getStr("ROLE_PERMGROUP_ID"))) {
                permGroupIdList.addAll(Splitter.on(",").splitToList(roleBeanList.get(i).getStr("ROLE_PERMGROUP_ID")));
            }
        }

        //角色权限构建
        List<DynaBean> rolePermBeanList = metaService.select("JE_RBAC_VROLEPERM", ConditionsWrapper.builder().in("JE_RBAC_ROLE_ID", roleIdList));
        Map<String, List<String>> rolePermMap = new HashMap<>();
        List<String> permList;
        List<String> eachRolePermGroupList;
        for (int i = 0; rolePermBeanList != null && !rolePermBeanList.isEmpty() && i < rolePermBeanList.size(); i++) {
            if (!rolePermMap.containsKey(rolePermBeanList.get(i).getStr("JE_RBAC_ROLE_ID"))) {
                permList = new ArrayList<>();
                rolePermMap.put(rolePermBeanList.get(i).getStr("JE_RBAC_ROLE_ID"), permList);
            } else {
                permList = rolePermMap.get(rolePermBeanList.get(i).getStr("JE_RBAC_ROLE_ID"));
            }
            if ("0".equals(rolePermBeanList.get(i).get("ROLEPERM_EXCLUDE_CODE"))) {
                if (!permList.contains(rolePermBeanList.get(i).getStr("PERM_CODE"))) {
                    permList.add(rolePermBeanList.get(i).getStr("PERM_CODE"));
                }
            } else {
                if (!"1".equals(rolePermBeanList.get(i).get("ROLEPERM_NOT_CHECKED"))) {
                    if (!permList.contains(rolePermBeanList.get(i).getStr("PERM_CODE"))) {
                        permList.add(rolePermBeanList.get(i).getStr("PERM_CODE"));
                    }
                }
            }
            if (!permList.contains(rolePermBeanList.get(i).getStr("PERM_CODE"))) {
                permList.add(rolePermBeanList.get(i).getStr("PERM_CODE"));
            }

            //权限组权限逻辑
            if (Strings.isNullOrEmpty(rolePermBeanList.get(i).getStr("ROLE_PERMGROUP_ID"))) {
                continue;
            }
            eachRolePermGroupList = Splitter.on(",").splitToList(rolePermBeanList.get(i).getStr("ROLE_PERMGROUP_ID"));
            for (String eachRolePermId : eachRolePermGroupList) {
                permList.addAll(permGroupPermCache.getCacheValue(eachRolePermId));
            }
        }

        rolePermCache.putMapCache(rolePermMap);
        return new AsyncResult<>(true);
    }

    @Override
    public Future<Boolean> removeRolePermCache(List<String> roleIdList) {
        if (roleIdList == null || roleIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        //清除相关账号
        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_VACCOUNTROLE", ConditionsWrapper.builder().in("ACCOUNTROLE_ROLE_ID", roleIdList));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; accountRoleBeanList != null && !accountRoleBeanList.isEmpty() && i < accountRoleBeanList.size(); i++) {
            accountIdList.add(accountRoleBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }
        accountPermissionCache.removeCache(accountIdList);
        funcPermissionCache.clear();
        rolePermCache.removeCache(roleIdList);
        return new AsyncResult<>(true);
    }

    @Override
    public Future<Boolean> reloadAllRolePermCache(boolean withPermGroup) {
        List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .ne("JE_RBAC_ROLE_ID", "ROOT")
                .ne("ROLE_DEVELOP", "1"));
        List<String> roleIdList = new ArrayList<>();
        for (int i = 0; roleBeanList != null && !roleBeanList.isEmpty() && i < roleBeanList.size(); i++) {
            roleIdList.add(roleBeanList.get(i).getStr("JE_RBAC_ROLE_ID"));
        }
        if (roleIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        return reloadRolePermCache(roleIdList, withPermGroup);
    }

    @Override
    public Future<Boolean> removeAllRolePermCache() {
        List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .ne("JE_RBAC_ROLE_ID", "ROOT")
                .ne("ROLE_DEVELOP", "1"));
        List<String> roleIdList = new ArrayList<>();
        for (int i = 0; roleBeanList != null && !roleBeanList.isEmpty() && i < roleBeanList.size(); i++) {
            roleIdList.add(roleBeanList.get(i).getStr("JE_RBAC_ROLE_ID"));
        }
        if (roleIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        removeRolePermCache(roleIdList);
        return new AsyncResult<>(true);
    }

    @Override
    @Async
    public Future<Boolean> reloadDevelopRolePermCache(List<String> developRoleIdList) {
        if (developRoleIdList == null || developRoleIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        //清除相关账号
        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_VACCOUNTROLE", ConditionsWrapper.builder().in("ACCOUNTROLE_ROLE_ID", developRoleIdList));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; accountRoleBeanList != null && !accountRoleBeanList.isEmpty() && i < accountRoleBeanList.size(); i++) {
            accountIdList.add(accountRoleBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }
        accountPermissionCache.removeCache(accountIdList);
        funcPermissionCache.asyncClear();
        developRolePermCache.removeCache(developRoleIdList);
        List<DynaBean> rolePermBeanList = metaService.select("JE_RBAC_VROLEPERM", ConditionsWrapper.builder().in("JE_RBAC_ROLE_ID", developRoleIdList));
        Map<String, List<String>> rolePermMap = new HashMap<>();
        List<String> permList;
        for (int i = 0; rolePermBeanList != null && !rolePermBeanList.isEmpty() && i < rolePermBeanList.size(); i++) {
            if (!rolePermMap.containsKey(rolePermBeanList.get(i).getStr("JE_RBAC_ROLE_ID"))) {
                permList = new ArrayList<>();
                rolePermMap.put(rolePermBeanList.get(i).getStr("JE_RBAC_ROLE_ID"), permList);
            } else {
                permList = rolePermMap.get(rolePermBeanList.get(i).getStr("JE_RBAC_ROLE_ID"));
            }
            if (!permList.contains(rolePermBeanList.get(i).getStr("PERM_CODE"))) {
                permList.add(rolePermBeanList.get(i).getStr("PERM_CODE"));
            }
        }
        developRolePermCache.putMapCache(rolePermMap);
        return new AsyncResult<>(true);
    }

    @Override
    public Future<Boolean> removeDevelopRolePermCache(List<String> roleIdList) {
        if (roleIdList == null || roleIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        //清除相关账号
        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_VACCOUNTROLE", ConditionsWrapper.builder().in("ACCOUNTROLE_ROLE_ID", roleIdList));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; accountRoleBeanList != null && !accountRoleBeanList.isEmpty() && i < accountRoleBeanList.size(); i++) {
            accountIdList.add(accountRoleBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }
        accountPermissionCache.removeCache(accountIdList);
        funcPermissionCache.clear();
        developRolePermCache.removeCache(roleIdList);
        return new AsyncResult<>(true);
    }

    @Override
    public Future<Boolean> reloadAllDevelopRolePermCache() {
        List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .ne("JE_RBAC_ROLE_ID", "ROOT")
                .eq("ROLE_DEVELOP", "1"));
        List<String> roleIdList = new ArrayList<>();
        for (int i = 0; roleBeanList != null && !roleBeanList.isEmpty() && i < roleBeanList.size(); i++) {
            roleIdList.add(roleBeanList.get(i).getStr("JE_RBAC_ROLE_ID"));
        }
        if (roleIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        return reloadDevelopRolePermCache(roleIdList);
    }

    @Override
    public Future<Boolean> removeAllDevelopRolePermCache() {
        List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .ne("JE_RBAC_ROLE_ID", "ROOT")
                .eq("ROLE_DEVELOP", "1"));
        List<String> roleIdList = new ArrayList<>();
        for (int i = 0; roleBeanList != null && !roleBeanList.isEmpty() && i < roleBeanList.size(); i++) {
            roleIdList.add(roleBeanList.get(i).getStr("JE_RBAC_ROLE_ID"));
        }
        if (roleIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        removeDevelopRolePermCache(roleIdList);
        return new AsyncResult<>(true);
    }

    @Override
    @Async
    public Future<Boolean> reloadDepartmentPermCache(List<String> departmentIdList) {
        if (departmentIdList == null || departmentIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_VACCOUNTDEPT", ConditionsWrapper.builder().in("ACCOUNTDEPT_DEPT_ID", departmentIdList));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; accountDeptBeanList != null && !accountDeptBeanList.isEmpty() && i < accountDeptBeanList.size(); i++) {
            accountIdList.add(accountDeptBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }
        accountPermissionCache.removeCache(accountIdList);
        funcPermissionCache.clear();
        departmentPermCache.removeCache(departmentIdList);
        List<DynaBean> departmentPermBeanList = metaService.select("JE_RBAC_VDEPTPERM", ConditionsWrapper.builder().in("JE_RBAC_DEPARTMENT_ID", departmentIdList));
        Map<String, List<String>> departmentPermMap = new HashMap<>();
        List<String> permList;
        for (int i = 0; departmentPermBeanList != null && !departmentPermBeanList.isEmpty() && i < departmentPermBeanList.size(); i++) {
            if (!departmentPermMap.containsKey(departmentPermBeanList.get(i).getStr("JE_RBAC_DEPARTMENT_ID"))) {
                permList = new ArrayList<>();
                departmentPermMap.put(departmentPermBeanList.get(i).getStr("JE_RBAC_DEPARTMENT_ID"), permList);
            } else {
                permList = departmentPermMap.get(departmentPermBeanList.get(i).getStr("JE_RBAC_DEPARTMENT_ID"));
            }
            if (!permList.contains(departmentPermBeanList.get(i).getStr("PERM_CODE"))) {
                permList.add(departmentPermBeanList.get(i).getStr("PERM_CODE"));
            }
        }
        departmentPermCache.putMapCache(departmentPermMap);
        return new AsyncResult<>(true);
    }

    @Override
    public Future<Boolean> removeDepartmentPermCache(List<String> departmentIdList) {
        if (departmentIdList == null || departmentIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_VACCOUNTDEPT", ConditionsWrapper.builder().in("ACCOUNTDEPT_DEPT_ID", departmentIdList));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; accountDeptBeanList != null && !accountDeptBeanList.isEmpty() && i < accountDeptBeanList.size(); i++) {
            accountIdList.add(accountDeptBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }
        accountPermissionCache.removeCache(accountIdList);
        funcPermissionCache.clear();
        departmentPermCache.removeCache(departmentIdList);
        return new AsyncResult<>(true);
    }

    @Override
    public Future<Boolean> reloadAllDepartmentPermCache() {
        List<DynaBean> departmentBeanList = metaService.select("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder()
                .ne("JE_RBAC_DEPARTMENT_ID", "ROOT"));
        List<String> departmentIdList = new ArrayList<>();
        for (int i = 0; departmentBeanList != null && !departmentBeanList.isEmpty() && i < departmentBeanList.size(); i++) {
            departmentIdList.add(departmentBeanList.get(i).getStr("JE_RBAC_DEPARTMENT_ID"));
        }
        if (departmentIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        return reloadDepartmentPermCache(departmentIdList);
    }

    @Override
    public Future<Boolean> removeAllDepartmentPermCache() {
        List<DynaBean> departmentBeanList = metaService.select("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder()
                .ne("JE_RBAC_DEPARTMENT_ID", "ROOT"));
        List<String> departmentIdList = new ArrayList<>();
        for (int i = 0; departmentBeanList != null && !departmentBeanList.isEmpty() && i < departmentBeanList.size(); i++) {
            departmentIdList.add(departmentBeanList.get(i).getStr("JE_RBAC_DEPARTMENT_ID"));
        }
        if (departmentIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        removeDepartmentPermCache(departmentIdList);
        return new AsyncResult<>(true);
    }

    @Override
    @Async
    public Future<Boolean> reloadPermGroupPermCache(List<String> permGroupIdList, boolean withRole) {
        if (permGroupIdList == null || permGroupIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        funcPermissionCache.clear();
        permGroupPermCache.removeCache(permGroupIdList);
        List<DynaBean> permGroupPermBeanList = metaService.select("JE_RBAC_VPERMGROUP", ConditionsWrapper.builder().in("JE_RBAC_PERMGROUP_ID", permGroupIdList));
        Map<String, List<String>> permGroupPermMap = new HashMap<>();
        List<String> permList;
        for (int i = 0; permGroupPermBeanList != null && !permGroupPermBeanList.isEmpty() && i < permGroupPermBeanList.size(); i++) {
            if (!permGroupPermMap.containsKey(permGroupPermBeanList.get(i).getStr("JE_RBAC_PERMGROUP_ID"))) {
                permList = new ArrayList<>();
                permGroupPermMap.put(permGroupPermBeanList.get(i).getStr("JE_RBAC_PERMGROUP_ID"), permList);
            } else {
                permList = permGroupPermMap.get(permGroupPermBeanList.get(i).getStr("JE_RBAC_PERMGROUP_ID"));
            }
            if (!permList.contains(permGroupPermBeanList.get(i).getStr("PERM_CODE"))) {
                permList.add(permGroupPermBeanList.get(i).getStr("PERM_CODE"));
            }
        }
        permGroupPermCache.putMapCache(permGroupPermMap);

        if (!withRole) {
            return new AsyncResult<>(true);
        }

        //找到需要重载的角色,并重新加载角色权限
        List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .ne("JE_RBAC_ROLE_ID", "ROOT")
                .ne("ROLE_DEVELOP", "1"));
        List<String> needRefreshRoleIdList = new ArrayList<>();
        List<String> rolePermIdList;
        boolean flag;
        for (int i = 0; roleBeanList != null && !roleBeanList.isEmpty() && i < roleBeanList.size(); i++) {
            flag = false;
            if (Strings.isNullOrEmpty(roleBeanList.get(i).getStr("ROLE_PERMGROUP_ID"))) {
                continue;
            }
            rolePermIdList = Splitter.on(",").splitToList(roleBeanList.get(i).getStr("ROLE_PERMGROUP_ID"));
            for (String eachPermId : permGroupIdList) {
                if (rolePermIdList.contains(eachPermId) && !needRefreshRoleIdList.contains(roleBeanList.get(i).getStr("JE_RBAC_ROLE_ID"))) {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                needRefreshRoleIdList.add(roleBeanList.get(i).getStr("JE_RBAC_ROLE_ID"));
                break;
            }
        }

        //清除相关账号
        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_VACCOUNTROLE", ConditionsWrapper.builder().in("ACCOUNTROLE_ROLE_ID", needRefreshRoleIdList));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; accountRoleBeanList != null && !accountRoleBeanList.isEmpty() && i < accountRoleBeanList.size(); i++) {
            accountIdList.add(accountRoleBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }
        accountPermissionCache.removeCache(accountIdList);

        reloadRolePermCache(needRefreshRoleIdList, false);

        return new AsyncResult<>(true);
    }

    @Override
    public void removePermGroupPermCache(List<String> permGroupIdList) {
        if (permGroupIdList == null || permGroupIdList.isEmpty()) {
            return;
        }
        funcPermissionCache.clear();
        permGroupPermCache.removeCache(permGroupIdList);
        //找到需要重载的角色,并重新加载角色权限
        List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .ne("JE_RBAC_ROLE_ID", "ROOT")
                .ne("ROLE_DEVELOP", "1"));
        List<String> needRefreshRoleIdList = new ArrayList<>();
        List<String> rolePermIdList;
        boolean flag;
        for (int i = 0; roleBeanList != null && !roleBeanList.isEmpty() && i < roleBeanList.size(); i++) {
            flag = false;
            if (Strings.isNullOrEmpty(roleBeanList.get(i).getStr("ROLE_PERMGROUP_ID"))) {
                continue;
            }
            rolePermIdList = Splitter.on(",").splitToList(roleBeanList.get(i).getStr("ROLE_PERMGROUP_ID"));
            for (String eachPermId : permGroupIdList) {
                if (rolePermIdList.contains(eachPermId) && !needRefreshRoleIdList.contains(roleBeanList.get(i).getStr("JE_RBAC_ROLE_ID"))) {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                needRefreshRoleIdList.add(roleBeanList.get(i).getStr("JE_RBAC_ROLE_ID"));
                break;
            }
        }
        removeRolePermCache(needRefreshRoleIdList);
    }

    @Override
    public Future<Boolean> reloadAllPermGroupPermCache(boolean withRole) {
        List<DynaBean> permGroupBeanList = metaService.select("JE_RBAC_PERMGROUP", ConditionsWrapper.builder()
                .ne("JE_RBAC_PERMGROUP_ID", "ROOT"));
        List<String> permGroupIdList = new ArrayList<>();
        for (int i = 0; permGroupBeanList != null && !permGroupBeanList.isEmpty() && i < permGroupBeanList.size(); i++) {
            permGroupIdList.add(permGroupBeanList.get(i).getStr("JE_RBAC_PERMGROUP_ID"));
        }
        if (permGroupIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        return reloadPermGroupPermCache(permGroupIdList, withRole);
    }

    @Override
    public void removeAllPermGroupPermCache() {
        List<DynaBean> permGroupBeanList = metaService.select("JE_RBAC_PERMGROUP", ConditionsWrapper.builder()
                .ne("JE_RBAC_PERMGROUP_ID", "ROOT"));
        List<String> permGroupIdList = new ArrayList<>();
        for (int i = 0; permGroupBeanList != null && !permGroupBeanList.isEmpty() && i < permGroupBeanList.size(); i++) {
            permGroupIdList.add(permGroupBeanList.get(i).getStr("JE_RBAC_PERMGROUP_ID"));
        }
        if (permGroupIdList.isEmpty()) {
            return;
        }
        removePermGroupPermCache(permGroupIdList);
    }

    @Override
    @Async
    public Future<Boolean> reloadOrgPermCache(List<String> orgIds) {
        if (orgIds == null || orgIds.isEmpty()) {
            return new AsyncResult<>(true);
        }

        List<DynaBean> orgAccountBeanList = metaService.select("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().in("SY_ORG_ID", orgIds));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; orgAccountBeanList != null && !orgAccountBeanList.isEmpty() && i < orgAccountBeanList.size(); i++) {
            accountIdList.add(orgAccountBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }

        accountPermissionCache.removeCache(accountIdList);
        funcPermissionCache.clear();
        orgPermCache.removeCache(orgIds);

        List<DynaBean> orgPermBeanList = metaService.select("JE_RBAC_VORGPERM", ConditionsWrapper.builder().in("JE_RBAC_ORG_ID", orgIds));
        Map<String, List<String>> orgPermMap = new HashMap<>();
        List<String> permList;
        for (int i = 0; orgPermBeanList != null && !orgPermBeanList.isEmpty() && i < orgPermBeanList.size(); i++) {
            if (!orgPermMap.containsKey(orgPermBeanList.get(i).getStr("JE_RBAC_ORG_ID"))) {
                permList = new ArrayList<>();
                orgPermMap.put(orgPermBeanList.get(i).getStr("JE_RBAC_ORG_ID"), permList);
            } else {
                permList = orgPermMap.get(orgPermBeanList.get(i).getStr("JE_RBAC_ORG_ID"));
            }
            if (!permList.contains(orgPermBeanList.get(i).getStr("PERM_CODE"))) {
                permList.add(orgPermBeanList.get(i).getStr("PERM_CODE"));
            }
        }
        orgPermCache.putMapCache(orgPermMap);
        return new AsyncResult<>(true);
    }

    @Override
    public Future<Boolean> removeOrgPermCache(List<String> orgIds) {
        if (orgIds == null || orgIds.isEmpty()) {
            return new AsyncResult<>(true);
        }
        List<DynaBean> orgAccountBeanList = metaService.select("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().in("SY_ORG_ID", orgIds));
        List<String> accountIdList = new ArrayList<>();
        for (int i = 0; orgAccountBeanList != null && !orgAccountBeanList.isEmpty() && i < orgAccountBeanList.size(); i++) {
            accountIdList.add(orgAccountBeanList.get(i).getStr("JE_RBAC_ACCOUNT_ID"));
        }
        accountPermissionCache.removeCache(accountIdList);
        funcPermissionCache.clear();
        orgPermCache.removeCache(orgIds);
        return new AsyncResult<>(true);
    }

    @Override
    public Future<Boolean> reloadAllOrgPermCache() {
        List<DynaBean> orgBeanList = metaService.select("JE_RBAC_ORG", ConditionsWrapper.builder().ne("ORG_CODE", "department").ne("ORG_CODE", "develop"));
        List<String> orgIdList = new ArrayList<>();
        for (int i = 0; orgBeanList != null && !orgBeanList.isEmpty() && i < orgBeanList.size(); i++) {
            orgIdList.add(orgBeanList.get(i).getStr("JE_RBAC_ORG_ID"));
        }
        if (orgIdList.isEmpty()) {
            return new AsyncResult<>(true);
        }
        return reloadOrgPermCache(orgIdList);
    }

    @Override
    public void removeAllOrgPermCache() {
        List<DynaBean> orgBeanList = metaService.select("JE_RBAC_ORG", ConditionsWrapper.builder().ne("ORG_CODE", "department").ne("ORG_CODE", "develop"));
        List<String> orgIdList = new ArrayList<>();
        for (int i = 0; orgBeanList != null && !orgBeanList.isEmpty() && i < orgBeanList.size(); i++) {
            orgIdList.add(orgBeanList.get(i).getStr("JE_RBAC_ORG_ID"));
        }
        if (orgIdList.isEmpty()) {
            return;
        }
        removeOrgPermCache(orgIdList);
    }

    @Override
    @Async
    public Future<Boolean> reloadUserPermCache(List<String> userIds) {
        funcPermissionCache.clear();
        List<DynaBean> userPermBeanList = metaService.select("JE_RBAC_VUSERPERM", ConditionsWrapper.builder().in("JE_RBAC_USER_ID", userIds));
        Map<String, List<String>> userPermMap = new HashMap<>();
        List<String> eachPermList;
        for (int i = 0; i < userPermBeanList.size(); i++) {
            if (userPermMap.containsKey(userPermBeanList.get(i).getStr("JE_RBAC_USER_ID"))) {
                eachPermList = userPermMap.get(userPermBeanList.get(i).getStr("JE_RBAC_USER_ID"));
            } else {
                eachPermList = new ArrayList<>();
                userPermMap.put(userPermBeanList.get(i).getStr("JE_RBAC_USER_ID"), eachPermList);
            }
            eachPermList.add(userPermBeanList.get(i).getStr("PERM_CODE"));
        }
        userPermCache.putMapCache(userPermMap);
        return new AsyncResult<>(true);
    }

    @Override
    public void removeUserPermCache(List<String> userIds) {
        funcPermissionCache.clear();
        userPermCache.removeCache(userIds);
    }

    @Override
    public void reloadAllUserPermCache() {
        List<DynaBean> userPermBeanList = metaService.select("JE_RBAC_VUSERPERM", ConditionsWrapper.builder());
        Map<String, List<String>> userPermMap = new HashMap<>();
        List<String> eachPermList;
        for (int i = 0; i < userPermBeanList.size(); i++) {
            if (userPermMap.containsKey(userPermBeanList.get(i).getStr("JE_RBAC_USER_ID"))) {
                eachPermList = userPermMap.get(userPermBeanList.get(i).getStr("JE_RBAC_USER_ID"));
            } else {
                eachPermList = new ArrayList<>();
                userPermMap.put(userPermBeanList.get(i).getStr("JE_RBAC_USER_ID"), eachPermList);
            }
            eachPermList.add(userPermBeanList.get(i).getStr("PERM_CODE"));
        }
        userPermCache.putMapCache(userPermMap);
    }

    @Override
    public Future<Boolean> removeAllUserPermCache() {
        List<DynaBean> userPermBeanList = metaService.select("JE_RBAC_VUSERPERM", ConditionsWrapper.builder());
        List<String> userIdList = new ArrayList<>();
        for (int i = 0; i < userPermBeanList.size(); i++) {
            if (!userIdList.contains(userPermBeanList.get(i).getStr("JE_RBAC_USER_ID"))) {
                userIdList.add(userPermBeanList.get(i).getStr("JE_RBAC_USER_ID"));
            }
        }
        userPermCache.removeCache(userIdList);
        return new AsyncResult<>(true);
    }

    @Override
    public void reloadAllTypedPermsCache() {
        reloadAllPermGroupPermCache(false);
        reloadAllRolePermCache(false);
        reloadAllDevelopRolePermCache();
        reloadAllDepartmentPermCache();
        reloadAllOrgPermCache();
        reloadAllUserPermCache();
    }

    @Override
    public void removeAllTypedPermsCache() {
        removeAllUserPermCache();
        removeAllDepartmentPermCache();
        removeAllDevelopRolePermCache();
        removeAllRolePermCache();
        removeAllOrgPermCache();
        removeAllPermGroupPermCache();
    }

    @Override
    public void removeAccountPermsCache(List<String> accountIdList) {
        accountPermissionCache.removeCache(accountIdList);
    }
}
